package bank.driver.sockets;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import bank.Account;
import bank.Bank;
import bank.InactiveException;
import bank.OverdrawException;
import bank.server.sockets.Response;
import bank.server.sockets.bank.*;

public class SocketBank implements Bank {
	
	private SocketMessenger messenger;

	public SocketBank(SocketMessenger messenger) {
		this.messenger = messenger;
	}

	@Override
	public String createAccount(String owner) throws IOException {
		Response resp = this.messenger.send(new CreateAccountRequest(owner));
		if (resp instanceof CreateAccountResponse) {
			return ((CreateAccountResponse)resp).getNumber();
		}
		throw new IOException("No Account generated");
	}

	@Override
	public Account getAccount(String number) throws IOException {
		Response resp = this.messenger.send(new GetAccountRequest(number));
		if (resp instanceof GetAccountResponse) {
			return new SocketAccount(
				((GetAccountResponse)resp).getOwner(), number, this.messenger
			);
		}
		throw new IOException("No Account");
	}

	@Override
	public Set<String> getAccountNumbers() throws IOException {
		Response resp = this.messenger.send(new GetAccountNumbersRequest());
		if (resp instanceof GetAccountNumbersResponse){
			String[] nrs = ((GetAccountNumbersResponse)resp).getNumbers();
			Set<String> nrSet = new HashSet<String>();
			for (int i = 0; i < nrs.length; i++) {
				nrSet.add(nrs[i]);
			}
			return nrSet;
		}
		throw new IOException();
	}

	@Override
	public boolean removeAccount(String number) throws IOException {
		Response resp = this.messenger.send(new RemoveAccountRequest(number));
		if (resp instanceof RemoveAccountResponse) {
			return ((RemoveAccountResponse)resp).getRemovePerformed();
		}
		throw new IOException();
	}

	@Override
	public void transfer(Account a, Account b, double amount) throws IOException,
	                                                                 IllegalArgumentException,
	                                                                 OverdrawException,
	                                                                 InactiveException {
		Response resp = this.messenger.send(
			new TransferRequest(a.getNumber(),b.getNumber(),amount)
		);
		if(resp instanceof TransferResponse) {
			Exception e = ((TransferResponse)resp).getException();
			if (e instanceof IllegalArgumentException) {
				throw (IllegalArgumentException)e;
			}
			else if (e instanceof OverdrawException) {
				throw (OverdrawException)e;
			}
			else if (e instanceof InactiveException) {
				throw (InactiveException)e;
			}
		} else {
			throw new IOException();
		}
	}

}
